package gitobject;

import java.io.*;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.Date;

import sha1.SHA1;
import repository.Repository;
import zlib.ZLibUtils;

public class Commit extends GitObject{
    protected String tree; 		// the sha1 value of present committed tree
    protected String parent; 	// the sha1 value of the parent commit
    protected String author; 	// the author's name
    protected String committer; // the committer's info
    protected String timestamp; // the timestamp for the commit
    protected String message; 	// the commit memo

    public String getParent(){return parent;}
    public String getTree(){return tree;}
    public String getAuthor(){return author;}
    public String getCommitter(){return committer;}
    public String getTimestamp(){return timestamp;}
    public String getMessage(){return message;}

    public Commit(){}
    /**
     * Construct a commit directly from a file.
     * @param
     * treePath, author, committer, message参数在git commit命令里创建
     * @throws Exception
     */
    public Commit(String treePath, String author, String committer, String message) throws Exception {
        this.fmt = "commit"; 	//type of object
        this.tree = new Tree(new File(treePath)).getKey(); // commit跟踪的tree
        this.parent = getLastCommit() == null ? "" : getLastCommit(); //null means there is no parent commit.
        this.author = author;
        this.committer = committer;
        this.timestamp = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Timestamp(System.currentTimeMillis()));
        this.message = message;

        /*Content of this commit, like this:
         *tree bd31831c26409eac7a79609592919e9dcd1a76f2
         *parent d62cf8ef977082319d8d8a0cf5150dfa1573c2b7
         *author xxx  1502331401 +0800
         *committer xxx  1502331401 +0800
         *修复增量bug
         * */
        this.value = "tree " + this.tree + "\nparent " + this.parent+ "\nauthor " + this.author +
                "\ncommitter " + this.committer + "\n" + this.timestamp + "\n" + this.message;
        
        key = genKey();
        compressWrite();

    }
    
    /**
     * Construct a commit from a built tree.
     * @param
     * t, author, committer, message参数在git commit命令里创建
     * @throws Exception
     */
    public Commit(Tree t, String author, String committer, String message) throws Exception {
        this.fmt = "commit"; 	//type of object
        this.tree = t.getKey(); 
        this.parent = getLastCommit() == null ? "" : getLastCommit(); //null means there is no parent commit.
        this.author = author;
        this.committer = committer;
        this.timestamp = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Timestamp(System.currentTimeMillis()));
        this.message = message;

        /*Content of this commit, like this:
         *tree bd31831c26409eac7a79609592919e9dcd1a76f2
         *parent d62cf8ef977082319d8d8a0cf5150dfa1573c2b7
         *author xxx  1502331401 +0800
         *committer xxx  1502331401 +0800
         *修复增量bug
         * */
        this.value = "tree " + this.tree + "\nparent " + this.parent+ "\nauthor " + this.author +
                "\ncommitter " + this.committer + "\n" + this.timestamp + "\n" + this.message;
        key = genKey();
        System.out.println(this.value);
        compressWrite();
    }
    
    /**
     * Deserialize the commit object from its key(commitId)
     * @param commitId
     * @return Commit
     */
    public static Commit deserialize(String commitId) {
        Commit commit = new Commit();
        try{
            // for writeObject() method
//            String curPath = "worktree"+ File.separator +".jit"+ File.separator +"objects" +
//                    File.separator + Id.substring(0, 2) + File.separator + Id.substring(2);
//            File f = new File(curPath);
            // 反序列化
//            ObjectInputStream in = new ObjectInputStream(new FileInputStream(f));
//            blob = (Blob) in.readObject();
            // for compressWrite() method
            String curPath = path +
                    File.separator + commitId.substring(0, 2) + File.separator + commitId.substring(2);
            File f = new File(curPath);
            FileInputStream fis = new FileInputStream(f);
            // 解压缩文件输入流
            byte[] compressedData = ZLibUtils.decompress(fis);
            // 执行解压缩
            byte[] data = ZLibUtils.decompress(compressedData);
            // 反序列化
            ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(data));
            commit = (Commit) in.readObject();
            in.close();
        }catch (Exception e){
            e.printStackTrace();
        }
//        System.out.println(commit.value);
        return commit;
    }

    /**
     * Generate the hash value of this commit.
     * @return String
     * @throws Exception
     */
    public String genKey() throws Exception {
        key = SHA1.getHash(value);
        return key;
    }

    /**
     * Get the parent commit from the HEAD file.
     * @return String
     * @throws IOException
     */
    public static String getLastCommit() throws IOException {
        File HEAD = new File(Repository.getGitDir() + File.separator + "HEAD");

        String path = getValue(HEAD).substring(5).replace("\n", ""); // refs/heads/master
        File branchFile = new File(Repository.getGitDir() + File.separator + path); // .jit/refs/heads/master

        if (branchFile.isFile()) {
            return getValue(branchFile); // return commit key
        } else {
            return null;
        }
    }
}

